import Vue from 'vue';

import { messageDuration, successCode } from '@/config/settings';
import { deepClone } from '@/utils/base';
import { treeTransArray, arrayTransTree } from '@/utils/treeUtil';
import { getToken } from '@/utils/auth';
import { setLocalData, getLocalData } from '@/utils/localStore';

import {
  getTree,
  addNode,
  renameNode,
  deleteNode,
  moveNode,
  goTopNode,
  goUpNode,
  goDownNode,
  goBottomNode,
} from '@/api/organization';

const showErrMsg = (message = '接口调用失败') => {
  Vue.prototype.$message({
    type: 'error',
    message,
    messageDuration,
  });
};

const checkedTree = (tree, checkId) => {
  return new Promise((resolve, reject) => {
    const transArr = treeTransArray(tree, 'organizationTreeVo');
    let checked = false;
    for (const item of transArr) {
      if (item.id === checkId) {
        checked = true;
        break;
      }
    }
    checked ? resolve(transArr) : reject();
  });
};

const state = {
  orgTree: [],
};

const getters = {
  orgTree: state => {
    if (Object.keys(state.orgTree).length <= 0 && getToken() !== '') {
      state.orgTree = getLocalData('orgTree') || [];
    }
    return state.orgTree;
  },
};

const mutations = {
  setOrgTree(state, orgTree) {
    state.orgTree = orgTree;
    setLocalData('orgTree', orgTree);
  },
  addTreeNode(state, treeNode, toFrist = false) {
    checkedTree(state.orgTree, treeNode.parentId)
      .then(transArr => {
        const node = deepClone(treeNode);
        const tree = arrayTransTree(toFrist ? [node, ...transArr] : [...transArr, node], {
          children: 'organizationTreeVo',
        });
        mutations.setOrgTree(state, tree);
      })
      .catch(() => {
        showErrMsg(`父节点[${treeNode.parentId}]未找到`);
      });
  },
  renameTreeNode(state, treeNode) {
    checkedTree(state.orgTree, treeNode.id).then(transArr => {
      for (const item of transArr) {
        if (item.id === treeNode.id) {
          item.deptName = treeNode.deptName;
          break;
        }
      }
      mutations.setOrgTree(state, arrayTransTree(transArr, { children: 'organizationTreeVo' }));
    });
  },
  deleteTreeNode(state, nodeId) {
    checkedTree(state.orgTree, nodeId).then(transArr => {
      const filterIds = [nodeId];
      const arr = transArr.filter(item => {
        if (filterIds.includes(item.parentId) && !filterIds.includes(item.id)) {
          filterIds.push(item.id);
        }
        return !filterIds.includes(item.id);
      });
      mutations.setOrgTree(state, arrayTransTree(arr, { children: 'organizationTreeVo' }));
    });
  },
  moveTreeNode(state, payload, toFrist = false) {
    checkedTree(state.orgTree, payload.id).then(transArr => {
      let temp;
      const arr = [];
      transArr.forEach(item => {
        if (item.id === payload.id) {
          temp = item;
          if (payload.parentId !== undefined) {
            temp.parentId = payload.parentId;
          }
        } else {
          arr.push(item);
        }
      });
      if (temp !== undefined) {
        toFrist ? arr.unshift(temp) : arr.push(temp);
      }
      mutations.setOrgTree(state, arrayTransTree(arr, { children: 'organizationTreeVo' }));
    });
  },
  goTopTreeNode(state, payload) {
    mutations.moveTreeNode(state, payload, true);
  },
  goUpTreeNode(state, payload) {
    checkedTree(state.orgTree, payload.id).then(transArr => {
      let temp, tempIndex;
      const arr = [];
      transArr.forEach((item, index) => {
        if (item.id === payload.id) {
          if (temp !== undefined && temp.parentId === item.parentId) {
            arr.splice(tempIndex, 0, item);
          } else {
            temp = item;
            arr.push(item);
          }
        } else {
          if (item.parentId === payload.parentId) {
            temp = item;
            tempIndex = index;
          }
          arr.push(item);
        }
      });
      mutations.setOrgTree(state, arrayTransTree(arr, { children: 'organizationTreeVo' }));
    });
  },
  goDownTreeNode(state, payload) {
    checkedTree(state.orgTree, payload.id).then(transArr => {
      // eslint-disable-next-line no-unused-vars
      let temp, tempIndex;
      const arr = [];
      transArr.forEach((item, index) => {
        if (item.id === payload.id) {
          temp = item;
          tempIndex = index;
        } else {
          arr.push(item);
          if (temp !== undefined && item.parentId === payload.parentId) {
            arr.push(temp);
            temp = undefined;
            // eslint-disable-next-line no-unused-vars
            tempIndex = undefined;
          }
        }
      });
      mutations.setOrgTree(state, arrayTransTree(arr, { children: 'organizationTreeVo' }));
    });
  },
  goBottomTreeNode(state, payload) {
    mutations.moveTreeNode(state, payload);
  },
};

const actions = {
  async initOrgTree({ commit }, organizationId) {
    const res = await getTree(organizationId);
    if (res.data && res.data.length > 0) {
      await commit('setOrgTree', res.data);
    }
  },
  async addTreeNode({ commit }, payload) {
    const res = await addNode(payload);
    if (successCode.includes(res.status)) {
      const treeNode = { ...res.data, parentId: res.data.parentId || -9999 };
      commit('addTreeNode', treeNode);
    }
    return res;
  },
  async renameTreeNode({ commit }, payload) {
    const res = await renameNode(payload);
    if (successCode.includes(res.status)) {
      commit('renameTreeNode', payload);
    }
  },
  async deleteTreeNode({ commit }, id) {
    const res = await deleteNode(id);
    if (successCode.includes(res.status)) {
      commit('deleteTreeNode', id);
    }
  },
  async moveTreeNode({ commit }, payload) {
    const res = await moveNode(payload);
    if (successCode.includes(res.status)) {
      commit('moveTreeNode', payload);
    }
  },
  async goTopTreeNode({ commit }, payload) {
    const res = await goTopNode(payload.id);
    if (successCode.includes(res.status)) {
      commit('goTopTreeNode', payload);
    }
  },
  async goUpTreeNode({ commit }, payload) {
    const params = {
      depetIds: [
        `${payload.id}-${payload.prev_departmentSort}`,
        `${payload.prev_id}-${payload.departmentSort}`,
      ],
    };
    const res = await goUpNode(params);
    if (successCode.includes(res.status)) {
      commit('goUpTreeNode', payload);
    }
  },
  async goDownTreeNode({ commit }, payload) {
    const params = {
      depetIds: [
        `${payload.id}-${payload.next_departmentSort}`,
        `${payload.next_id}-${payload.departmentSort}`,
      ],
    };
    const res = await goDownNode(params);
    if (successCode.includes(res.status)) {
      commit('goDownTreeNode', payload);
    }
  },
  async goBottomTreeNode({ commit }, payload) {
    console.log(payload.id);
    const res = await goBottomNode(payload.id);
    if (successCode.includes(res.status)) {
      commit('goBottomTreeNode', payload);
    }
  },
};

export default { state, getters, mutations, actions };
